package db;




import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import runnable_functions.ReferedObject;

import details.*;





// synchronized - will be added in the implementing class


/**
 * @author AnnaG
 *
 */
public interface DataBase {

	
	
	/**
	 * 
	 * "opens" the connection
	 */
	public void openConnection();
	
	
	/**
	 * close the connection
	 */
	public void closeConnection();
	
	


			///////////////////////////////////////////////////////////////////
			/////////////////       SEARCH  METHODS      //////////////////////
			///////////////////////////////////////////////////////////////////




	/**
	 * DISCID includes genre id
	 * @return - returns CD title, genre name, length, it's track list 
	 * (+ track numbers, lengths, tracks titles and tracks performers in case it's various artists cd), performer, year
	 * @throws - throws SQLException 
	 * 
	 */
	public Cd searchBy_DISCID(String DISCID) throws SQLException;


	//=====================================================================================================

	
	/**
	 * 
	 * @return CD's Tracks
	 * @throws SQLException
	 */
	public ArrayList<Track> getCDTracks(String DISCID) throws SQLException;
	

	
	//=====================================================================================================
	
	
	/**
	 * @return - return Song - contains song name , artist , numOfViews, comments, numOfLikes and lyrics of that song
	 * @throws - throws SQLException 
	 * 
	 */
	public Song searchBySongID(int songID) throws SQLException;
	
	
	//=====================================================================================================

	
	/**
	 * @return - returns Cds of that artist (as performer) - it's DISCID,  title, genre, year, length, artist-name
	 * and numOfLikes, numOfViews of that artist
	 * @throws - throws SQLException 
	 * 
	 */
	public Artist searchByArtistID(int artistID) throws SQLException;


	//=====================================================================================================

	
	// if user wants exact search of artist - first find it (and get its id) and then call SearchByArtistID to get more info



	/**
	 * @return - returns top nomOfResults of Artists (names and IDs)
	 * @throws - throws SQLException 
	 */

	public ArrayList<Artist> searchByArtist(String artistName , int nomOfResults) throws SQLException;




	//=====================================================================================================


	/**
	 * @return - returns top nomOfResults Cds (DISCID, title, performer, genre, length, year). 
	 * Some of the parameters maybe empty (year = XXXX)
	 * @throws - throws SQLException 
	 * 
	 * this is exact search
	 */
		
	
	public ArrayList<Cd> advanceCDSearch(String cdTitle, String performer, String genre, int yearFrom,int yearTo, int nomOfResults) throws SQLException;	

	//=====================================================================================================
	
	/**
	 * @return - returns top nomOfResults Songs (lyrics returned only when words!=null). 
	 * Some of the parameters maybe empty (year = XXXX)
	 * @throws - throws SQLException 
	 * 
	 * this is exact search
	 */
	
	public ArrayList<Song> advanceSongSearch(String artistName, String song_title, String words, int nomOfResults) throws SQLException;	



  //=====================================================================================================


				/////////////////////////////////////////////////////////////////
				/////////////////       EDIT   METHODS     //////////////////////
				/////////////////////////////////////////////////////////////////




	/**
	 * 
	 * in case cd's genre won't be mentioned, genre_dir_name will be written
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 * @throws IllegalStateException 
	 * @throws InterruptedException 
	 * @throws - throws SQLException 
	 * 
	 */

	public void updateFromFreeDB(ArrayList<Cd> cds,String dirName) throws SQLException, IllegalStateException, IOException, ParserConfigurationException, SAXException, InterruptedException;  

	//=====================================================================================================

	
	
	/**
	 * Add new cd to DB. cd will include all needed data (including track list)
	 * @throws - throws SQLException  
	 * 
	 */


	public void  addCD(Cd cd) throws SQLException;

	
	//=====================================================================================================


	/**
	 * adds tracks of specific cd
	 * @throws SQLException 
	 * 
	 */
				
		
		public void addTracksToDisc(ArrayList<Track> changedCdTracks) throws SQLException;
		


	//==================================================================================
	
	

	/**
	 * 
	 * songID should be in DB already
	 * lyrics is the lyrics itself and not the file path of it
	 * this song shouldn't have lyrics in DB yet
	 * 
	 * @throws - throws SQLException  
	 * 
	 */


	public void addLyrics(int songID, String lyrics) throws SQLException;

	//=====================================================================================================


	/**
	 * DISCID includes genre id
	 * one or more of cdTitle, cdYear, performer, length maybe empty (for example - if admin wants to change only CD title)
	 * DISCID should be in DB already
	 * 
	 * editing performer - means changing cd's performer (e.g. changes like madona to beatles)
	 * if you want to edit performer (e.g. madonna instead of madona) use method edit
	 * 
	 * @throws - throws SQLException
	 * 
	 */


	public void editCD(String DISCID, String cdTitle, int cdYear, String performer, int cdlength) throws SQLException;

	//=====================================================================================================

	
		/**
		 * only mistake editing!!! 
		 * genre should be already in DB
		 * @throws SQLException 

		 * 
		 */
	
	public void editGenre(String genre , String newGenre) throws SQLException, Exception ;
	
	//=====================================================================================================
	


	/**
	 * only mistake editing!!!
	 * edit Artist or Song or Lyrics
	 * targetID should be already in table represented by target
	 * @throws SQLException 
	 * 
	 */


	public void edit(int refObjID ,ReferedObject refObj, String newData) throws SQLException, Exception;
	//=====================================================================================================




	/**
	 * DISCID includes genre name
	 * DISCID should be in DB already
	 * this will also delete all the tracks in that cd      
	 * 
	 * @throws - throws SQLException  
	 * 
	 */


	public void deleteCD(String DISCID) throws SQLException;

	//=====================================================================================================


	/**
	 * deletes empty cds from database
	 * @throws SQLException  
	 * 
	 */
	
	public void deleteEmptyCds() throws SQLException ;
	//=====================================================================================================
	
	/**
	 * 
	 * artistId should be in DB already
	 * 
	 * this will also delete all songs (which may cause deleting other tracks, comments and lyrics as well), 
	 * tracks and cds by this artist
	 * 
	 * @throws - throws SQLException  
	 * 
	 */


	public void deleteArtist(int artistID) throws SQLException;

	//=====================================================================================================

	/**
	 * deletes track from a specific cd
	 * (meaning, this song can stay in the database, but only not in this cd)
	 * trackID should be in DB already
	 * trackID combined from DISCID (which includes genre id) and track number in CD
	 * 
	 * @throws - throws SQLException
	 * 
	 */


	public void deleteTrack(String trackID) throws SQLException;

	//=====================================================================================================

	
	/**
	 * deletes all tracks from a specific cd
	 * trackID should be in DB already
	 * trackID combined from DISCID (which includes genre id) and track number in CD
	 * 
	 * @throws - throws SQLException
	 * 
	 */
	
	public void deleteAllTracks(String DISCID) throws SQLException;
	
	//=====================================================================================================
	

	/**
	 * deletes song from all cds containing it. 
	 * If the artist of that song doesn't have any other songs, it will be deleted as well
	 * songID should be in DB already
	 * 
	 * @throws - throws SQLException  
	 * 
	 */
	public void deleteSong(int songID) throws SQLException;


	//=====================================================================================================


	/**
	 * 
	 * genre should be in DB already
	 * 
	 * This will automatically delete all cds from that genre!!!!
	 * @throws - throws SQLException  
	 * 
	 */


	public void deleteGenre(String genre) throws SQLException;
	//=====================================================================================================




	/**
	 * 
	 * songID should be in DB already
	 * 
	 * @throws - throws SQLException  
	 * 
	 */


	public void deleteLyrics(int songID) throws SQLException;

	//=====================================================================================================



			/////////////////////////////////////////////////////////////////
			/////////////////       USER METHODS       //////////////////////
			/////////////////////////////////////////////////////////////////




	/**
	 *  user_name shouldn't be already in DB
	 * @throws - throws SQLException  
	 * 
	 */

	public int addUser(String user_name, String user_pass) throws SQLException;

	//=====================================================================================================


	/**
	 * userName should be already in DB and shouldn't be admin!!
	 * 
	 * @throws - throws SQLException  
	 * 
	 */

	public void deleteUser(String userName) throws SQLException;
	//=====================================================================================================

	/**
	 * userName should be already in DB
	 * this method should be called only(!!) after user logged in
	 * 
	 * @throws - throws SQLException  
	 * 
	 */

	public void changePass(String userName, String new_user_pass) throws SQLException;
	//=====================================================================================================

	/**
	 * 
	 * @return user's name and it's password
	 * @throws - throws SQLException  
	 * 
	 */
	public User findUser(String user_name) throws SQLException;

	//=====================================================================================================


				/////////////////////////////////////////////////////////////
				/////////////////       Likings Methods        //////////////
				/////////////////////////////////////////////////////////////



	/**
	 * target = Cd or Artist or Song ( see Target enum)
	 * 
	 * if target isn't Cd, then targetID is originally int, so we'll change it back to int
	 * if target is Cd, then it includes genre id as well
	 * targetID and user_id should be already in DB
	 * 
	 * l = LIKE for liking and l=UNLIKE for unliking
	 * 
	 * @throws - throws SQLException  
	 * 
	 */

	public void like_UnLike(String targetID,Target target, Like l,  int user_id) throws SQLException;
	
	//=====================================================================================================

		

	/** target = Cd or Artist or Song (see the enum - Target)
	 * if target isn't Cd, then targetID is originally int, so we'll change it back to int
	 * if target is Cd, then it includes genre name as well
	 * targetID should be already in DB
	 * @return target_id and NumOfCDRatings
	 * @throws - throws SQLException  
	 * 
	 */
	public int getNumOfLikes(String target_id, Target target) throws SQLException;


	//=====================================================================================================

	/**
	 * target = Cd or Artist or Song (see the enum - Target)
	 * if target isn't Cd, then targetID is originally int, so we'll change it back to int
	 * if target is Cd, then it includes genre id as well
	 * targetID should be already in DB
	 * @return true if user liked the object represented by target and target_id and false otherwise
	 * @throws - throws SQLException  
	 * 
	 */

	public boolean isUserLike(String target_id, Target target, int userID) throws SQLException;
	
	
	
	/////////////////       Comments       //////////////////////



	/**
	 * 
	 * songID and user_id should be already in DB
	 * DATETIME  is from this format 'YYYY-MM-DD HH:MM:SS'
	 *
	 * @throws - throws SQLException  
	 * 
	 */


	public void addSongComment(int songID, int user_id, String DATETIME, String comment ) throws SQLException;
	//=====================================================================================================


	
	/**
	 * 
	 * commentID should be already in DB
	 * DATETIME  is from this format 'YYYY-MM-DD HH:MM:SS'
	 *
	 * @throws - throws SQLException  
	 * 
	 */

	public void editSongComment(int commentID,String new_DATETIME, String new_comment ) throws SQLException;
	//=====================================================================================================
	
	
	
	/**
	 * 
	 * commentID should be already in DB
	 * @throws - throws SQLException  
	 * 
	 */

	public void deleteSongComment(int commentID ) throws SQLException;
	//=====================================================================================================
	
	
	/**
	 * 
	 * songID should be already in DB
	 * @return userName-comment-DATETIME "combinations"
	 *
	 * @throws - throws SQLException  
	 * 
	 */

	public ArrayList<Comment> getSongComments(int songID) throws SQLException;

	//=====================================================================================================


				/////////////////////////////////////////////////////////////////
				/////////////////       Views  Methods     //////////////////////
				/////////////////////////////////////////////////////////////////

	/**
	 * target = Cd or Artist or Song ( see Target enum)
	 * 
	 * if target isn't Cd, then targetID is originally int, so we'll change it back to int
	 * if target is Cd, then it includes genre name as well
	 * targetID should be already in DB
	 * 
	 * @throws - throws SQLException  
	 * 
	 */

	public void addView(String targetID, Target target) throws SQLException;
	
	//=====================================================================================================

		

	/** target = Cd or Artist or Song (see the enum - Target)
	 * f target isn't Cd, then targetID is originally int, so we'll change it back to int
	 * if target is Cd, then it includes genre name as well
	 * targetID should be already in DB
	 * @return NumOfViews
	 * @throws - throws SQLException  
	 * 
	 */
	public int getNumOfViews(String target_id, Target target) throws SQLException;


	//=====================================================================================================


	/**
	 * 
	 * 
	 * @return TOP5 viewed Cds - id, title, performer, year,genre
	 * @throws SQLException 
	 *  
	 * 
	 */
	public ArrayList<Cd> getTOP_5_CDs() throws SQLException;


	//=====================================================================================================

	/**
	 * 
	 * 
	 * @return TOP5 viewed artists - ids, names
	 * @throws SQLException  
	 * 
	 */
	public ArrayList<Artist> getTOP_5_Artists() throws SQLException;

	//=====================================================================================================


	/**
	 * 
	 * 
	 * @return TOP5 viewed songs - ids, names
	 * @throws SQLException  
	 * 
	 */
	public ArrayList<Song> getTOP_5_Songs() throws SQLException;

	//=====================================================================================================


}
